// Queue.cpp: implementation of the CQueue class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Queue.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
/*OS_SEM OSSemCreate(WORD count);
   OS_SEM OSSemCreate(WORD count, WORD max);
   OS_SEM NewPeriodicSemaphore(DWORD dwMilliseconds);
   void OSSemDel(OS_SEM sem);
   void OSSemPend(OS_SEM sem);
   WORD OSSemPend(OS_SEM sem, DWORD timeout);
   void OSSemPost(OS_SEM sem);
 */

CQueue::CQueue()
{
}

CQueue::~CQueue()
{
    RemoveAll();
    delete [] m_pvMsgs;
}


bool CQueue::Init(int nMaxMsgs)
{
    m_nMaxMsgs = nMaxMsgs;
    m_pvMsgs = new void*[m_nMaxMsgs];

    if (m_pvMsgs == NULL)
    {
        //Debug(1, ("CQueue::Init : critical error : sys out of memory !!!!!!!!!!!\r\n"));
        return false;
    }

    for (int i = 0; i < m_nMaxMsgs; i++) //��ʼ����Ϣָ��
    {
        m_pvMsgs[i] = NULL;
    }
    m_nFirst = m_nLast = 0;
    m_nMsgNum = 0;

    m_hsemSpace = OSSemCreate(m_nMaxMsgs, m_nMaxMsgs);
    m_hsemMail = OSSemCreate(0, m_nMaxMsgs);
    m_hmtxQ = OSSemCreate(1);

    return true;
}


//������ɾ��������ȫ��ָ�룬���ͷ�����ռ�õĿռ�
void CQueue::RemoveAll()
{
    while (Remove(1) != NULL)
    {
        ;                       //LINUXƽ̨��0��ʾ���޵ȴ�,���Ա�����1
    }
}

bool CQueue::Append(void* pvMsg, DWORD dwMilliseconds)
{
    if (OSSemPend(m_hsemSpace, dwMilliseconds) != SYS_ERR_OK)
    {                                                //�ȵȴ��������пռ���ʼ�
        //Debug(DB_QUEUE, ("CQueue::Append(): no space to append Queue %p. \r\n", this));
        return false;
    }

    OSSemPend(m_hmtxQ);        //ȡ�ö������ռ��

    m_pvMsgs[m_nLast++] = pvMsg;   //������Ϣ���е�ͷ

    if (m_nLast == m_nMaxMsgs)     //Խ��ѭ�����еı߽�
    {
        m_nLast = 0;
    }

    m_nMsgNum++;

    OSSemPost(m_hsemMail);   //��һ���µ���Ϣ�ˣ�
    OSSemPost(m_hmtxQ);      //�ͷŶ������ռ��

    return true;
}


void* CQueue::Remove(DWORD dwMilliseconds)
{
    if (OSSemPend(m_hsemMail, dwMilliseconds) != SYS_ERR_OK) //�ȵȴ����������ʼ�
    {
        //Debug(OP_DEBUG, ("CQueue::Remove(): no msg to remove from Queue %p. \r\n", this));
        return NULL;
    }

    OSSemPend(m_hmtxQ);         //ȡ�ö������ռ��

    void* pvMsg;
    pvMsg = m_pvMsgs[m_nFirst];     //������Ϣ
    m_pvMsgs[m_nFirst] = NULL;

    m_nFirst++;                     //βָ��++����ʹ����msg==NULL��++��ʾ���
    if (m_nFirst == m_nMaxMsgs)     //Խ��ѭ�����еı߽�
    {
        m_nFirst = 0;
    }

    m_nMsgNum--;

    OSSemPost(m_hsemSpace);  //���µĿռ��ˣ�
    OSSemPost(m_hmtxQ);      //�ͷŶ������ռ��

    return pvMsg;
}


